import { GraphQLModule } from '@nestjs/graphql';
import { Logger, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { PrismaModule, loggingMiddleware } from 'nestjs-prisma';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppResolver } from './app.resolver';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { PostsModule } from './posts/posts.module';
import config from './common/configs/config';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { GqlConfigService } from './gql-config.service';
 

/**
 * 职责: 负责组织应用程序的结构。它将相关的 Controller、Service、Resolver 等组件组合在一起，形成一个功能模块。

特点:

使用 @Module() 装饰器定义。  

包含 imports、controllers、providers 和 exports 等属性。

每个模块可以独立运行，也可以被其他模块导入。

使用场景: 用于模块化应用程序，便于管理和扩展。

providers 	由 Nest 注入器实例化的提供者，并且可以至少在整个模块中共享 
`  provider 一般包含 Services、Repositories、  Factories , Values , Classes  等。`
controllers 	必须创建的一组控制器
imports 	导入模块的列表，这些模块导出了此模块中所需提供者 
`  import ,export  针对的是其他 @Module 
exports 	由本模块提供并应在其他模块中可用的提供者的子集

示例:
typescript 

@Module({
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

 */
@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true, load: [config] }),
    PrismaModule.forRoot({
      isGlobal: true,
      prismaServiceOptions: {
        middlewares: [
          // configure your prisma middleware
          loggingMiddleware({
            logger: new Logger('PrismaMiddleware'),
            logLevel: 'log',
          }),
        ],
      },
    }),

    GraphQLModule.forRootAsync<ApolloDriverConfig>({
      driver: ApolloDriver,
      useClass: GqlConfigService,
    }),

    AuthModule,
    UsersModule,
    PostsModule,
  ],
  controllers: [AppController],
  providers: [AppService, AppResolver],
})
export class AppModule {}


/** 
 * Middleware（中间件）
职责: 在请求到达 Controller 或 Resolver 之前，或者在响应发送给客户端之前，执行一些额外的逻辑。

特点:

可以访问请求和响应对象。

可以用于日志记录、身份验证、请求验证等。

使用 @Injectable() 装饰器定义，并实现 NestMiddleware 接口。

使用场景: 处理跨切面关注点（如日志、身份验证）。

示例:

typescript
复制
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: Function) {
    console.log('Request...');
    next();
  }
  
 */

  /**
   * 
   *  Interceptor（拦截器）
职责: 在请求处理之前或之后，拦截并修改请求或响应。

特点:

可以用于日志记录、缓存、错误处理、响应格式化等。

使用 @Injectable() 装饰器定义，并实现 NestInterceptor 接口。

使用场景: 处理请求和响应的全局逻辑。

示例:

typescript
复制
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler) {
    console.log('Before...');
    return next.handle().pipe(tap(() => console.log('After...')));
  }
}


   */
  
/**
 *  Guard（守卫）
职责: 用于保护路由，决定是否允许请求继续处理（如身份验证、权限检查）。

特点:

使用 @Injectable() 装饰器定义，并实现 CanActivate 接口。

可以访问请求上下文（如请求头、用户信息）。

使用场景: 路由级别的权限控制。

示例:

typescript
复制
@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request); // 自定义验证逻辑
  }
}
 */

/** 
 * pipe（管道）
职责: 用于转换或验证输入数据（如请求参数、请求体）。

特点:

使用 @Injectable() 装饰器定义，并实现 PipeTransform 接口。

可以用于数据转换（如字符串转数字）或验证（如检查字段是否为空）。

使用场景: 数据预处理和验证。

示例:

typescript
复制
@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    if (!value) {
      throw new BadRequestException('Value is required');
    }
    return value;
  }
} 
 */

/**
 * Exception Filter（异常过滤器）
职责: 捕获并处理应用程序中抛出的异常。

特点:

使用 @Catch() 装饰器定义，并实现 ExceptionFilter 接口。

可以自定义异常响应格式。

使用场景: 全局异常处理。

示例:

typescript
复制
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const status = exception.getStatus();

    response.status(status).json({
      statusCode: status,
      message: exception.message,
    });
  }
}

 */

/**
 * Provider（提供者）
职责: 提供可注入的依赖项（如服务、仓库、工具类）。

特点:

使用 @Injectable() 装饰器定义。

可以是服务、工厂、值、类等。

使用场景: 依赖注入的核心组件。

示例:

typescript
复制
@Injectable()
export class UsersService {
  findAll(): string {
    return 'All users';
  }
}

 */

/**
 *  Repository（仓库）
职责: 封装与数据库的交互逻辑（如 CRUD 操作）。

特点:

通常与 ORM（如 TypeORM、Prisma）结合使用。

使用 @Injectable() 装饰器定义。

使用场景: 数据库操作。

示例:

typescript
复制
@Injectable()
export class UsersRepository {
  constructor(@InjectRepository(User) private userRepository: Repository<User>) {}

  findAll(): Promise<User[]> {
    return this.userRepository.find();
  }
}

 */
/**
 * Configuration（配置）
职责: 管理应用程序的配置（如环境变量、数据库连接信息）。

特点:

使用 @nestjs/config 模块加载配置。

支持 .env 文件和动态配置。

使用场景: 配置管理。

示例:

typescript
复制
@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}

 */

/** 
 * Event Emitter（事件发射器）
职责: 用于发布和订阅事件，实现解耦的业务逻辑。

特点:

使用 @nestjs/event-emitter 模块。

支持同步和异步事件处理。

使用场景: 事件驱动的业务逻辑。

示例:

typescript
复制
@Injectable()
export class UserCreatedEvent {
  constructor(public readonly userId: number) {}
}

@Injectable()
export class UserService {
  constructor(private eventEmitter: EventEmitter2) {}

  createUser() {
    this.eventEmitter.emit('user.created', new UserCreatedEvent(1));
  }
}

 */
/** 
 * 
 * Task Scheduling（任务调度）
职责: 用于执行定时任务或周期性任务。

特点:

使用 @nestjs/schedule 模块。

支持 Cron 表达式、间隔任务和超时任务。

使用场景: 定时任务处理。

示例:

typescript
复制
@Injectable()
export class TasksService {
  @Cron('45 * * * * *')
  handleCron() {
    console.log('Called every minute at 45 seconds');
  }
}
 */

/**
 * WebSockets（WebSocket 网关）
职责: 用于实现实时双向通信（如聊天应用、实时通知）。

特点:

使用 @WebSocketGateway() 装饰器定义。

支持消息订阅和广播。

使用场景: 实时通信。

示例:

typescript
复制
@WebSocketGateway()
export class ChatGateway {
  @SubscribeMessage('message')
  handleMessage(client: any, payload: any): string {
    return 'Hello world!';
  }
}
 * 
 */

/** 
 *  Health Check（健康检查）
职责: 用于监控应用程序的运行状态。

特点:

使用 @nestjs/terminus 模块。

支持数据库、内存、磁盘等健康检查。

使用场景: 应用程序监控。

示例:

typescript
复制
@Controller('health')
export class HealthController {
  constructor(private health: HealthCheckService) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([]);
  }
}
 */
/** 
 * File Upload（文件上传）
职责: 用于处理文件上传。

特点:

使用 @nestjs/platform-express 或 @nestjs/platform-fastify。

支持单文件和多文件上传。

使用场景: 文件上传功能。

示例:

typescript
复制
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
} 
 */